﻿/**
 * ListIterator
 *
 * @author		Allen Chou
 * @version		1.0.1 (last update: Jan 17 2009)
 * @link        http://cjcat.blogspot.com
 * @link		http://cjcat2266.deviantart.com
 */

package idv.cjcat.ds {

	/**
	 * A <code>ListIterator</code> object represents an iterator for the <code>List</code> class.
	 */
	public class ListIterator implements Iterator {
		
		/** @private */
		internal var _node:ListNode;
		/** @private */
		internal var _list:List;
		
		/**
		 * You don't directly instantiate a list iterator through the constructor.
		 * Instead, use the <code>List.getIterator()</code> method.
		 */
		public function ListIterator(node:ListNode, list:List) {
			this._node = node;
			this._list = list;
		}
		
		/**
		 * @inheritDoc
		 */
		public function begin():void {
			this._node = _list._head;
		}
		
		/**
		 * @inheritDoc
		 */
		public function end():void {
			this._node = _list._tail;
		}
		
		/**
		 * @inheritDoc
		 */
		public function next():void {
			this._node = this._node.next;
		}
		
		/**
		 * @inheritDoc
		 */
		public function prev():void {
			this._node = this._node.prev;
		}
		
		/**
		 * @inheritDoc
		 */
		public function hasNext():Boolean {
			return Boolean(this._node.next != null);
		}
		
		/**
		 * @inheritDoc
		 */
		public function hasPrev():Boolean {
			return Boolean(this._node.prev != null);
		}
		
		/**
		 * The node carrying the current item pointed by the iterator.
		 * This is for checking if an iterator is pointing to a null value in a loop.
		 * @example
		 * <listing>
		 * var list:List = new List(1, 2, 3, 4, 5);
		 * var it:ListIterator = list.getIterator();
		 * for (it.begin(); it.node != null; it.next()) trace(it.data);</listing>
		 */
		public function get node():ListNode { return _node; }
		public function get list():List { return _list; }
		
		/**
		 * @inheritDoc
		 */
		public function get data():* {
			if (this._node == null) return null;
			return this._node.data;
		}
		
		/**
		 * Creates a clone of the iterator.
		 * @return  The clone.
		 */
		public function clone():ListIterator {
			return new ListIterator(this._node, this._list);
		}
		
	}
}